package task_synchronization

import (
	"context"
	"testing"
	"time"

	"v8s-api/internal/db"
	"v8s-api/test/support"

	resourcename "v8s/resource-name"

	"go.mongodb.org/mongo-driver/bson"
)

func Test(t *testing.T, ctx *support.ApplicationContext, folder string) {
	// Arrange:
	ctx.MongoHelper.InsertProjects("task-synchronization/" + folder + "/fixture-mongodb.json")

	//ctx.MongoHelper.WriteProjects(t, "task-synchronization/"+folder+"/expected-mongodb.json")

}

func TestCreate(t *testing.T, ctx *support.ApplicationContext) {
	databaseRepository := ctx.MongoHelper.GetDbProjects()

	meta := map[string]interface{}{"test": "test"}

	compose := bson.M{
		"version":  "2",
		"services": bson.M{"service": bson.M{"image": "test-docker-image"}}}

	mockedDate := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
	rn, err := resourcename.ParseResourceName("rn:b:c:d:e:new-tasks:new-task")
	if err != nil {
		panic(" error test create")
	}
	taskToCreate := db.Task{
		ID:         "new-task",
		RN:         rn,
		Metadata:   meta,
		Compose:    compose,
		CreatedAt:  mockedDate,
		ModifiedAt: mockedDate,
		Status:     db.TaskStatusCreationRequest,
	}

	_, err = databaseRepository.CreateTask(
		context.Background(),
		"new-tasks",
		taskToCreate)
	if err != nil {
		panic(" error test create")
	}

}

func TestCreateUP(t *testing.T, ctx *support.ApplicationContext) {
	databaseRepository := ctx.MongoHelper.GetDbProjects()
	meta := bson.M{"test": "test"}

	compose := bson.M{
		"version":  "2",
		"services": bson.M{"service": bson.M{"image": "test-docker-image"}}}

	mockedDate := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)

	rn, err := resourcename.ParseResourceName("rn:b:c:d:e:existing-tasks-not-locked:new-task")
	if err != nil {
		panic(" error test create")
	}

	taskToCreate := db.Task{
		ID:         "new-task",
		TN:         "new-task",
		RN:         rn,
		Metadata:   meta,
		Compose:    compose,
		CreatedAt:  mockedDate,
		ModifiedAt: mockedDate,
		Status:     db.TaskStatusCreationRequest,
	}
	_, err = databaseRepository.CreateTask(
		context.Background(),
		"existing-tasks-not-locked",
		taskToCreate)
	if err != nil {
		panic(" error test create upsert")
	}
}

func TestUpdate(t *testing.T, ctx *support.ApplicationContext) {
	databaseRepository := ctx.MongoHelper.GetDbProjects()
	meta := map[string]interface{}{"a": "b"}
	compose := bson.M{
		"version":  "2",
		"services": bson.M{"service": bson.M{"image": "test-docker-image"}}}
	rn, _ := resourcename.ParseResourceName("rn:b:c:d:e:existing-tasks-not-locked:existing-task--to-update-listed")
	_, err := databaseRepository.UpdateTask(context.Background(),
		rn,
		compose,
		meta,
	)
	if err != nil {
		panic(" error test update")
	}
}

func TestSuspend(t *testing.T, ctx *support.ApplicationContext) {
	databaseRepository := ctx.MongoHelper.GetDbProjects()
	rn, _ := resourcename.ParseResourceName("rn:b:c:d:e:existing-tasks-not-locked:existing-task--to-suspend-listed")
	err := databaseRepository.UpdateTaskStatus(
		context.Background(),
		rn,
		db.TaskStatusSuspensionRequest,
		[]db.TaskStatus{db.TaskStatusRunning})
	if err != nil {
		panic(" error test suspend")
	}
}

func TestResume(t *testing.T, ctx *support.ApplicationContext) {
	databaseRepository := ctx.MongoHelper.GetDbProjects()
	rn, _ := resourcename.ParseResourceName("rn:b:c:d:e:existing-tasks-not-locked:existing-task--to-resume-listed")
	err := databaseRepository.UpdateTaskStatus(
		context.Background(),
		rn,
		db.TaskStatusResumeRequest,
		[]db.TaskStatus{db.TaskStatusSuspended})
	if err != nil {
		panic(" error test resume")
	}
}

func TestDelete(t *testing.T, ctx *support.ApplicationContext) {
	databaseRepository := ctx.MongoHelper.GetDbProjects()

	rn, _ := resourcename.ParseResourceName("rn:b:c:d:e:existing-tasks-not-locked:existing-task--to-delete-listed")
	err := databaseRepository.UpdateTaskStatus(
		context.Background(),
		rn,
		db.TaskStatusDeletionRequest,
		[]db.TaskStatus{db.TaskStatusRunning})

	if err != nil {
		panic(" error test delete")
	}
}

func TestGet(t *testing.T, ctx *support.ApplicationContext, expected string) {
	databaseRepository := ctx.MongoHelper.GetDbProjects()
	rn, _ := resourcename.ParseResourceName("rn:b:c:d:e:existing-tasks-not-locked:existing-task--to-get-listed")
	task, isexist, err := databaseRepository.GetTask(context.Background(), rn)
	if err != nil {
		panic(" error in getting task")
	}
	if !isexist {
		panic(" error in getting task: task not exists")
	}
	ctx.MongoHelper.AssertTasks(t, []db.Task{task}, expected)
}

func TestList(t *testing.T, ctx *support.ApplicationContext, expected string) {
	databaseRepository := ctx.MongoHelper.GetDbProjects()
	tasks, err := databaseRepository.FindTasks(
		context.Background())
	if err != nil {
		panic(" error in listing task")
	}
	ctx.MongoHelper.AssertTasks(t, tasks, expected)
}

func TestSearch(t *testing.T, ctx *support.ApplicationContext, expected string) {
	databaseRepository := ctx.MongoHelper.GetDbProjects()
	mockedDate := time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
	tasks, err := databaseRepository.FindTasksUpdatedAfter(
		context.Background(),
		mockedDate,
		map[string]interface{}{},
		100)
	if err != nil {
		panic(" error in searching task")
	}
	ctx.MongoHelper.AssertTasks(t, tasks, expected)
}
